package com.holly.unit.deform;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.holly.unit.auth.api.SessionManagerApi;
import com.holly.unit.auth.api.pojo.login.LoginUser;
import com.holly.unit.db.api.factory.PageResultFactory;
import com.holly.unit.db.api.pojo.db.TableFieldInfo;
import com.holly.unit.db.api.pojo.db.TableInfo;
import com.holly.unit.db.api.pojo.druid.DruidProperties;
import com.holly.unit.db.api.pojo.page.PageResult;
import com.holly.unit.db.api.util.DatabaseUtil;
import com.holly.unit.deform.api.DeformComponentApi;
import com.holly.unit.deform.api.pojo.component.DeformDeptTreeDTO;
import com.holly.unit.deform.api.pojo.component.DeformDictDTO;
import com.holly.unit.deform.api.pojo.component.DeformUserDTO;
import com.holly.unit.deform.api.util.OrgChildrenUtil;
import com.holly.unit.deform.context.DeformContext;
import com.holly.unit.deform.mapper.DeformDataMapper;
import com.holly.unit.dict.modular.entity.SysDict;
import com.holly.unit.dict.modular.pojo.request.DictRequest;
import com.holly.unit.dict.modular.service.DictService;
import com.holly.unit.jwt.api.exception.JwtException;
import com.holly.unit.jwt.api.exception.enums.JwtExceptionEnum;
import com.holly.unit.system.api.OrganizationServiceApi;
import com.holly.unit.system.api.UserOrgServiceApi;
import com.holly.unit.system.api.UserServiceApi;
import com.holly.unit.system.api.exception.SystemModularException;
import com.holly.unit.system.api.exception.enums.user.SysUserExceptionEnum;
import com.holly.unit.system.api.pojo.organization.HrOrganizationDTO;
import com.holly.unit.system.api.pojo.user.SysUserDTO;
import com.holly.unit.system.api.pojo.user.SysUserOrgDTO;
import com.holly.unit.system.api.pojo.user.request.SysUserRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类描述: 表单组件扩展操作类
 *
 * @author fxr
 * @version 1.0.0
 * @date 2022/4/15 15:30
 */
@Slf4j
public class DeformComponentOperator implements DeformComponentApi {

    private UserServiceApi userServiceApi = DeformContext.userServiceApi();
    private SessionManagerApi sessionManagerApi = DeformContext.sessionManagerApi();
    private OrganizationServiceApi organizationServiceApi = DeformContext.organizationServiceApi();

    private DictService dictService = DeformContext.dictService();


    @Autowired
    private DeformDataMapper deformDataMapper;

    @Autowired
    private UserOrgServiceApi userOrgServiceApi;


    @Override
    public Map<String, Object> fetchUserSectionInfoByToken(String token) {

        LoginUser user = sessionManagerApi.getSession(token);
        String username = ObjectUtil.isNull(user) ? null : user.getAccount();
        if (username == null) {
            throw new JwtException(JwtExceptionEnum.JWT_PARSE_ERROR, token);
        }
        log.info(" ------ 通过令牌获取部分用户信息，当前用户： " + username);
        // 查询用户信息
        SysUserDTO sysUserDTO = userServiceApi.getUserInfoByUserId(user.getUserId());

        SysUserOrgDTO sysUserOrg = userOrgServiceApi.getUserOrgByUserId(sysUserDTO.getUserId());

        if (ObjectUtil.isNull(sysUserDTO)) {
            throw new SystemModularException(SysUserExceptionEnum.USER_NOT_EXIST, user);
        }
        String sysOrgCode = ObjectUtil.isNull(sysUserDTO.getOrgId()) ? "" :
                ObjectUtil.isNull(organizationServiceApi.detailByOrgId(sysUserDTO.getOrgId())) ? "" :
                        organizationServiceApi.detailByOrgId(sysUserDTO.getOrgId()).getOrgCode();


        Map<String, Object> map = new HashMap<String, Object>();
        map.put("sysUserId", sysUserDTO.getUserId());
        map.put("sysUserCode", sysUserDTO.getAccount()); // 当前登录用户登录账号
        map.put("sysUserName", sysUserDTO.getRealName()); // 当前登录用户真实名称
        map.put("sysOrgCode", sysOrgCode); // 当前登录用户部门编号
        map.put("sysOrgId", ObjectUtil.isNull(sysUserOrg) ? "" : sysUserOrg.getOrgId());

        log.info(" ------ 通过令牌获取部分用户信息，已获取的用户信息： " + map);
        return map;
    }

    @Override
    public PageResult<DeformUserDTO> fetchPageSysUsers(SysUserRequest sysUserRequest) {
        PageResult<SysUserDTO> pageResult = userServiceApi.queryPage(sysUserRequest);
        List<DeformUserDTO> dtos = new ArrayList<>();
        pageResult.getRows().stream().forEach(entity -> {
            DeformUserDTO dto = new DeformUserDTO();
            dto.setId(ObjectUtil.isNull(entity.getUserId()) ? "" : entity.getUserId().toString());
            dto.setUsername(ObjectUtil.isNull(entity.getAccount()) ? "" : entity.getAccount());
            dto.setRealname(ObjectUtil.isNull(entity.getRealName()) ? "" : entity.getRealName());
            dto.setPost(ObjectUtil.isNull(entity.getRoleName()) ? "" : entity.getRoleName());
            dto.setSex(ObjectUtil.equal("M", entity.getSex()) ? 1 : 2);
            dto.setPhone(ObjectUtil.isNull(entity.getPhone()) ? "" : entity.getPhone());
            dto.setEmail(ObjectUtil.isNull(entity.getEmail()) ? "" : entity.getEmail());
            dtos.add(dto);
        });
        return createUserDtoPageResult(pageResult, dtos);
    }

    @Override
    public PageResult<DeformDictDTO> fetchPageDict(DictRequest dictRequest) {

        PageResult<SysDict> pageResult = dictService.findPage(dictRequest);
        List<DeformDictDTO> dtos = new ArrayList<>();

        pageResult.getRows().stream().forEach(entity -> {
            DeformDictDTO dto = new DeformDictDTO();
            dto.setId(ObjectUtil.isNull(entity.getDictId()) ? "" : entity.getDictId().toString());
            dto.setDictName(entity.getDictName());
            dto.setDictCode(entity.getDictCode());
            dtos.add(dto);
        });
        return createDictDtoPageResult(pageResult, dtos);
    }


    @Override
    public List<DeformDeptTreeDTO> fetchTreeList() {
        List<HrOrganizationDTO> list = organizationServiceApi.orgList();
        List<DeformDeptTreeDTO> listResult = OrgChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }


    @Override
    public Map<String, Object> fetchDbTableListInfo(String token, DruidProperties druidProperties) {

        LoginUser user = sessionManagerApi.getSession(token);
        String username = ObjectUtil.isNull(user) ? null : user.getAccount();
        if (username == null) {
            throw new JwtException(JwtExceptionEnum.JWT_PARSE_ERROR, token);
        }
        log.info(" ------ 通过令牌获取数据库中表信息，当前用户： " + username);

        List<TableInfo> tableInfos = DatabaseUtil.selectTables(druidProperties);

        if (ObjectUtil.isNotNull(tableInfos) && tableInfos.size() > 0) {
            for (TableInfo table : tableInfos) {
                if (ObjectUtil.isNull(table.getTableComment()) || "".equals(table.getTableComment())) {
                    table.setTableComment(table.getTableName());
                }
            }
        }
        //循环过滤掉act和sys开头的数据
        Map<String, Object> rst = new HashMap<>();
        rst.put("tables", tableInfos);
        return rst;
    }

    @Override
    public Map<String, Object> fetchDbTableColListInfo(String token, DruidProperties druidProperties, String tableName) {
        LoginUser user = sessionManagerApi.getSession(token);
        String username = ObjectUtil.isNull(user) ? null : user.getAccount();
        if (username == null) {
            throw new JwtException(JwtExceptionEnum.JWT_PARSE_ERROR, token);
        }
        log.info(" ------ 通过令牌获取数据库中表字段信息，当前用户： " + username);

        List<TableFieldInfo> tableFields = DatabaseUtil.getTableFields(druidProperties, tableName);

        if (ObjectUtil.isNotNull(tableFields) && tableFields.size() > 0) {
            for (TableFieldInfo table : tableFields) {
                if (ObjectUtil.isNull(table.getColumnComment()) || "".equals(table.getColumnComment())) {
                    table.setColumnComment(table.getCamelFieldName());
                }
            }
        }

        Map<String, Object> rst = new HashMap<>();
        rst.put("tableCols", tableFields);
        return rst;
    }


    @Override
    public PageResult<Map> getTableDataByColumn(Integer pageNum, Integer pageSize, String tableName, List<String> columnList) {
        Page<Map> pageQuery = new Page<>(pageNum, pageSize);
        IPage<Map> page = deformDataMapper.getTableDataByColumn(pageQuery, tableName, columnList);

        PageResult<Map> result = PageResultFactory.createPageResult(page.getRecords(),
                page.getTotal(), pageSize, pageNum);

        return result;
    }


    private PageResult<DeformUserDTO> createUserDtoPageResult(PageResult<SysUserDTO> pageResult, List<DeformUserDTO> dtos) {

        PageResult<DeformUserDTO> res = new PageResult<>();
        res.setRows(dtos);
        res.setTotalRows(Convert.toInt(pageResult.getTotalRows()));
        res.setPageNo(pageResult.getPageNo());
        res.setPageSize(pageResult.getPageSize());
        res.setTotalPage(PageUtil.totalPage(pageResult.getTotalRows(), pageResult.getPageSize()));
        return res;

    }

    private PageResult<DeformDictDTO> createDictDtoPageResult(PageResult<SysDict> pageResult, List<DeformDictDTO> dtos) {

        PageResult<DeformDictDTO> res = new PageResult<>();
        res.setRows(dtos);
        res.setTotalRows(Convert.toInt(pageResult.getTotalRows()));
        res.setPageNo(pageResult.getPageNo());
        res.setPageSize(pageResult.getPageSize());
        res.setTotalPage(PageUtil.totalPage(pageResult.getTotalRows(), pageResult.getPageSize()));
        return res;

    }

}
